﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Media;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace WindowsFormsApp1
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            ShowInfo();
            ShowFriendList();
        }
        int SH;
        int SW;
        int self_SH;
        int self_SW;
        int star_win_flag = 1;//窗口初始化位置标志位,防止隐藏窗口后定时器重新跑窗口函数再次在初始化位置打开
        
        #region 主窗口停靠功能,停靠屏幕边缘时自动隐藏
        private void MainForm_Load(object sender, EventArgs e)
        {
            //获取显示器屏幕的大小,不包括任务栏、停靠窗口
            SH = Screen.PrimaryScreen.WorkingArea.Height;
            SW = Screen.PrimaryScreen.WorkingArea.Width;
            //获取当前活动窗口高度跟宽度
            self_SH = this.Size.Height;
            self_SW = this.Size.Width;
            if (star_win_flag == 1)
            {
                //设置窗口打开的位置为下方居中
                SetDesktopLocation((SW - self_SW) / 2, SH - self_SH);
                star_win_flag = 0;
            }
            //============添加窗体所在位置定时检测=================
            TopMost = true; //把窗体设置为最顶层
            System.Windows.Forms.Timer MyTimer = new System.Windows.Forms.Timer();
            MyTimer.Tick += new EventHandler(StopRectTimer_Tick);
            MyTimer.Interval = 100;
            MyTimer.Enabled = true;
        }
        //=================隐藏窗体&显示部分==================
        int check_flag = 0; //窗体隐藏标志位，0为不开启隐藏功能，初始默认0
        int win = 0;
        int frmX;
        int frmY;
        private void StopRectTimer_Tick(object sender, EventArgs e)
        {
            // 获取窗体位置
            frmX = this.Location.X;
            frmY = this.Location.Y;

            if (check_flag == 1)
            {
                //获取窗口的边沿与桌面的间距，判断窗口是否靠近边沿里面-1个位置
                if (this.Left <= 0) //获取控件左边沿与桌面左边沿的间距，窗口靠近左边桌面边沿         
                    win = 1;
                else if (this.Top <= 0 && this.Left > 0 && this.Right < SW - 1)////获取控件上边沿与桌面上边沿的间距，窗口靠近顶端桌面边沿 
                    win = 2;
                else if (this.Right >= SW) ////获取控件右边沿与桌面左边沿的间距，窗口靠近右边桌面边沿  
                    win = 3;
                else //窗体没有靠近边沿
                    win = 0;

                /* Cursor.Position获取当前鼠标的位置
                 * Bounds.Contains(Cursor.Position)获取鼠标位置是否在窗口边界里面，在返回ture
                 *如果鼠标在窗体上，则根据停靠位置显示整个窗体
                 *窗体边沿计算是以左边沿为主*/

                if (Bounds.Contains(Cursor.Position))
                {
                    switch (win)
                    {
                        case 1:
                            this.Opacity = 1.0f;    //窗口恢复不透明状态
                                                    //窗体靠近左沿时，鼠标在窗体显示完整窗体 
                            SetDesktopLocation(0, frmY);
                            break;
                        case 2:
                            this.Opacity = 1.0f;    //窗口恢复不透明状态
                                                    //窗体靠近顶部时，鼠标在窗体显示完整窗体  
                            SetDesktopLocation(frmX, 0);
                            break;
                        case 3:
                            this.Opacity = 1.0f;    //窗口恢复不透明状态
                                                    //窗体靠近右沿时，鼠标在窗体显示完整窗体 
                            SetDesktopLocation(SW - self_SW, frmY);
                            break;
                    }
                }

                //如果鼠标离开窗体，则根据停靠位置隐藏窗体（即把窗体显示出桌面以外），但须留出部分窗体边缘以便鼠标选中窗体，这里留7个位置
                else
                {
                    switch (win)
                    {
                        case 1:
                            this.Opacity = 0.2f; //窗口百分之80透明
                                                 //窗体靠近左沿时，鼠标不在窗体时隐藏 
                            SetDesktopLocation(20 - self_SW, frmY);
                            break;
                        case 2:
                            this.Opacity = 0.2f; //窗体靠近顶部时，鼠标不在窗体时隐藏  
                            SetDesktopLocation(frmX, 20 - self_SH);
                            break;
                        case 3:
                            this.Opacity = 0.2f; //窗体靠近右沿时，鼠标不在窗体时隐藏  
                            SetDesktopLocation(SW - 20, frmY);
                            break;
                    }
                }
            }
        }
        /*==========窗体边沿隐藏功能开启选择框===========*/
        private void isHideCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (isHideCheckBox.CheckState == CheckState.Checked) //判断复选框选中

            {
                check_flag = 1;
                //if(win==0)//判断框功能选中时，判断窗口不在边沿时自动收到上边沿中间隐藏
                {
                    this.Opacity = 0.2f; //窗口半透明                   
                    SetDesktopLocation((SW - self_SW) / 2, 20 - SH);
                }

                //MessageBox.Show("checkbox1 is checked\n" + checkBox1.Text);

            }

            else if (isHideCheckBox.CheckState == CheckState.Unchecked) //判断复选框没选中

            {
                check_flag = 0;
                //MessageBox.Show("checkbox1 is Unchecked\n" + checkBox1.Text);

            }
        }
        #endregion

        int fromUserID;                                 //消息发送者
        int friendHeadID;                               //发消息好友的头像ID  
        int messageImageIndex = 0;                          //工具栏中的消息图标的索引
        public static string nickName = "";                     //自己的昵称
        public static string strFlag = "[离线]";
        DataOperator dataOper = new DataOperator();
        public void ShowInfo()
        {
            string connectionString = "Server=47.110.75.86;Database=oodata;User=root;Password=123456Ab!;Pooling=true;Min Pool Size=2;Max Pool Size=50;";
            MySqlConnection connection = new MySqlConnection(connectionString);
            int headID = 0;
 //           string sql = "select NickName, HeadID,Sign from tb_User where ID=" + publicClass.loginID + "";
            string sql = "select * from tb_User";
            MySqlCommand command = new MySqlCommand(sql, connection);
            try
            {
                connection.Open();
                MySqlDataReader reader = command.ExecuteReader();
                if (reader.Read())
                {
                    nickName = reader["NickName"].ToString();
                    headID = (int)reader["HeadID"];
                    strFlag = reader["Sign"].ToString();
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取用户信息失败！" + ex.Message);
            }
            finally
            {
                connection.Close();
                this.Text = publicClass.loginID.ToString();
                pBoxHead.Image = imageListHead.Images[headID];
                lblName.Text = nickName + '（' + publicClass.loginID + '）';
            }
        }

        private void ShowFriendList()
        {
            string connectionString = "Server=47.110.75.86;Database=oodata;User=root;Password=123456Ab!;";
            MySqlConnection connection = new MySqlConnection(connectionString);
            lvFriend.Items.Clear();
            string sql = "select FriendID,NickName,HeadID,Flag from tb_User,tb_Friend where tb_Friend.HostID=" + publicClass.loginID + " and tb_User.ID=tb_Friend.FriendID";
            MySqlCommand command = new MySqlCommand(sql, connection);
            try
            {
                connection.Open();
                MySqlDataReader reader = command.ExecuteReader();
                int i = lvFriend.Items.Count;
                while (reader.Read())
                {
                    string strFriendName = reader["NickName"].ToString();
                    if(strFriendName.Length < 9)
                    {
                        strFriendName = strFriendName.PadRight(9, ' ');
                    }
                    else
                    {
                        strFriendName = (strFriendName.Substring(0,2) + "...").PadRight(9, ' ');
                    }
                    if (reader["Flag"].ToString() == "0")
                    {
                        strFlag = "[离线]";
                    }
                    else
                    {
                        strFlag = "[在线]";
                    }
                    lvFriend.Items.Add(reader["FriendID"].ToString(), strFriendName + strFlag, (int)reader["HeadID"]);
                    lvFriend.Items[i].Group = lvFriend.Groups[0];
                    i++;
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取好友列表失败！" + ex.Message);
            }
            finally
            {
                connection.Close();
            }
        }

        private void Frm_Main_Load(object sender, EventArgs e)
        {
            tsbtnMessageReading.Image = imgListMessage.Images[0];   //工具栏的消息图标
            ShowInfo();                                         //显示个人信息
            ShowFriendList();                                       //显示好友列表
        }

        private void tsbtnInfo_Click(object sender, EventArgs e)
        {
 //           Frm_EditInfo frmInfo = new Frm_EditInfo();              //创建个人信息窗体对象
 //           frmInfo.Show();                         //显示个人信息窗体
        }
        private void tsbtnSearchFriend_Click(object sender, EventArgs e)
        {
//            Frm_AddFriend frmAddFriend = new Frm_AddFriend();       //创建查找好友窗体对象
//            frmAddFriend.Show();
        }
        private void tsbtnUpdateFriendList_Click(object sender, EventArgs e)
        {
            ShowFriendList();
        }
        private void tsbtnMessageReading_Click(object sender, EventArgs e)
        {
            tmAddFriend.Stop();                                 //停止消息提醒定时器
            messageImageIndex = 0;                              //头像恢复正常
                                                                //显示正常的系统消息提醒图标
            tsbtnMessageReading.Image = imgListMessage.Images[messageImageIndex];
 //           Frm_Remind frmRemind = new Frm_Remind();                //创建系统消息窗体对象
 //           frmRemind.Show();                                       //显示系统消息窗体
        }
        private void tsbtnExit_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("确实要退出吗？", "确认", MessageBoxButtons.YesNo,
        MessageBoxIcon.Question);                               //弹出确定对话框
            if (result == DialogResult.Yes)                     //如果单击是按钮
            {
                Application.ExitThread();                           //退出当前程序
            }
        }
        Frm_Chat frmChat;

        //双击打开聊天窗体
        private void lvFriend_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lvFriend.SelectedItems.Count > 0)//判断是否有选中项
            {

                if (frmChat == null)//判断聊天窗体对象是否为空
                {
                    frmChat = new Frm_Chat();//创建聊天窗体对象
                    string connectionString = "Server=47.110.75.86;Database=oodata;User=root;Password=123456Ab!;Pooling=true;Min Pool Size=2;Max Pool Size=50;";
                    MySqlConnection connection = new MySqlConnection(connectionString);
                    //记录聊天的账号
                    frmChat.friendID = Convert.ToInt32(lvFriend.SelectedItems[0].Name);
                    frmChat.nickName = dataOper.GetDataSet("select NickName from tb_User where ID=" + frmChat.friendID).Tables[0].Rows[0][0].ToString();//记录昵称
                    frmChat.headID = Convert.ToInt32(dataOper.GetDataSet("select HeadID from tb_User where ID=" + frmChat.friendID).Tables[0].Rows[0][0]) + 1;//记录头像ID
                    frmChat.ShowDialog();//以对话框显示聊天窗体对象
                    frmChat = null;//将聊天窗体对象设置为空
                }
                if (tmChat.Enabled == true)//如果聊天定时器处于可用状态
                {
                    tmChat.Stop();//停止聊天定时器
                    lvFriend.SelectedItems[0].ImageIndex = friendHeadID;//将选中项的头像显示为正常状态
                }
            }
        }
        private bool HasShowUser(int ID)
        {
            //是否在当前显示出的用户列表中找到了该用户
            bool find = false;
            //循环lvFriend中的2个组，寻找发消息的人是否在列表中
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < lvFriend.Groups[i].Items.Count; j++)
                {
                    if (Convert.ToInt32(lvFriend.Groups[i].Items[j].Name) == ID)
                    {
                        find = true;
                    }
                }
            }
            return find;
        }
        private void UpdateStranger(int ID)
        {
            lvFriend.Items.Clear();                             //清空原来的列表
                                                                //获取指定用户的昵称及头像ID
            string connectionString = "Server=47.110.75.86;Database=oodata;User=root;Password=123456Ab!;";
            MySqlConnection connection = new MySqlConnection(connectionString);
            string sql = "select NickName, HeadID from tb_User where ID=" + ID;
            MySqlCommand command = new MySqlCommand(sql, connection);
            connection.Open();
            MySqlDataReader reader = command.ExecuteReader();           //执行查询
            int i = lvFriend.Items.Count;                               //记录添加到ListView中的项索引
            while (reader.Read())                               //循环添加陌生人列表
            {
                string strTemp = reader["NickName"].ToString(); //记录好友昵称
                                                                    //对好友昵称进行处理
                string strName = strTemp;
                if (strTemp.Length < 9)
                    strName = strTemp.PadLeft(9, ' ');
                else
                    strName = (strTemp.Substring(0, 2) + "...").PadLeft(9, ' ');
                //向ListView中添加项，Name:用户ID，值：昵称，要显示的头像
                lvFriend.Items.Add(fromUserID.ToString(), strName, (int)reader["HeadID"]);
                lvFriend.Items[i].Group = lvFriend.Groups[1];       //设置项的分组为陌生人
                i++;                                                //临时变量加1
            }
            reader.Close();                                 //关闭读取器
            connection.Close();                        //关闭数据库连接
        }
        private void tmMessage_Tick(object sender, EventArgs e)
        {
            if (lvFriend.SelectedItems.Count > 0)               //判断好友列表中有选中项
            {
                if (lvFriend.SelectedItems[0].Group == lvFriend.Groups[0])//如果选中项属于第1组
                {
//                    tsMenuDel.Visible = true;                   //显示删除菜单
//                    tsMenuAdd.Visible = false;                  //隐藏添加好友菜单
                }
                //如果选中项属于第2组
                else if (lvFriend.SelectedItems[0].Group == lvFriend.Groups[1])
                {
//                    tsMenuDel.Visible = false;                  //隐藏删除菜单
//                    tsMenuAdd.Visible = true;                   //显示添加好友菜单
                }
            }
            int messageTypeID = 1;                      //消息类型
            int messageState = 1;                       //消息状态
            string connectionString = "Server=47.110.75.86;Database=oodata;User=root;Password=123456Ab!;";
            MySqlConnection connection = new MySqlConnection(connectionString);
            string sql = "select top 1 FromUserID, MessageTypeID, MessageState from tb_Message where ToUserID = " + publicClass.loginID + " and MessageState = 0";		//查找未读消息对应的好友ID
            MySqlCommand command = new MySqlCommand(sql, connection);
            connection.Open();
            MySqlDataReader reader = command.ExecuteReader();     //执行查询
            if (reader.Read())                      //读取未读消息
            {
                fromUserID = (int)reader["FromUserID"];         //记录消息发送者
                messageTypeID = (int)reader["MessageTypeID"];       //记录消息类型
                messageState = (int)reader["MessageState"];         //记录消息状态
            }
            reader.Close();                         //关闭读取器
            connection.Close();                    //关闭数据库连接
                                                                //消息有两种类型：聊天消息、添加好友消息
                                                                //判断消息类型，如果是添加好友消息，启动消息提醒定时器
            if (messageTypeID == 2 && messageState == 0)
            {
                SoundPlayer player = new SoundPlayer("system.wav");     //系统消息提示
                player.Play();                          //播放指定声音文件
                tmAddFriend.Start();                        //启动消息提醒定时器
            }
            //如果是聊天消息，启动聊天定时器，使好友头像闪烁
            else if (messageTypeID == 1 && messageState == 0)
            {
                sql = "select HeadID from tb_User where ID=" + fromUserID;//获取消息发送者的ID
                friendHeadID = (int)dataOper.ExecSQL(sql);           //记录消息发送者的头像ID
                                                                        //如果发消息的人不在好友列表中，将其添加到陌生人列表中
                if (!HasShowUser(fromUserID))
                {
                    UpdateStranger(fromUserID);                         //显示陌生人列表
                }
                SoundPlayer player = new SoundPlayer("msg.wav");        //聊天消息提示
                player.Play();                          //播放指定声音文件
                tmChat.Start();                         //启动聊天定时器
            }
        }
        private void tmAddFriend_Tick(object sender, EventArgs e)
        {
            messageImageIndex = messageImageIndex == 0 ? 1 : 0;         //实时获取系统消息图像索引
                                                                        //工具栏中显示消息读取状态图像
            tsbtnMessageReading.Image = imgListMessage.Images[messageImageIndex];
        }
        private void tmChat_Tick(object sender, EventArgs e)
        {
            //循环好友列表两个组中的每项，找到消息发送者，使其头像闪烁
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < lvFriend.Groups[i].Items.Count; j++)
                {
                    //判断是否为消息发送者
                    if (Convert.ToInt32(lvFriend.Groups[i].Items[j].Name) == fromUserID)
                    {
                        if (frmChat != null && frmChat.friendID != 0)
                        {
                            //直接显示头像，避免闪烁效果
                            lvFriend.SelectedItems[0].ImageIndex = friendHeadID;
                        }
                        else
                        {
                            if (lvFriend.Groups[i].Items[j].ImageIndex < 100)
                            {
                                //索引为100的图片是一个空白图片，为了实现闪烁效果
                                lvFriend.Groups[i].Items[j].ImageIndex = 100;
                            }
                            else
                            {
                                //要显示的消息发送者头像索引
                                lvFriend.Groups[i].Items[j].ImageIndex = friendHeadID;
                            }
                        }
                    }
                }
            }
        }
        private void minimizeButton_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void closeButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void settingsButton_Click(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void pBoxHead_Click(object sender, EventArgs e)
        {

        }

    }
}
